<template>
  <div class="face-compare-page">
    <h2 class="page-title">人脸1:1比对</h2>

    <div class="upload-row">
      <!-- 第一张图片上传区域 -->
      <div class="upload-col">
        <p class="label-text">第一张比对图片</p>
        <el-upload
          class="upload-box"
          action="#"
          :auto-upload="false"
          :on-change="handleFileChange1"
          :file-list="fileList1"
          :before-remove="handleBeforeRemove"
          accept="image/jpg,image/jpeg,image/png,image/bmp"
          list-type="picture-card"
        >
          <i class="el-icon-plus upload-plus"></i>
        </el-upload>
        <p class="format-desc">
          支持格式: JPG/JPEG/PNG/BMP<br>
          当前格式: <span class="current-format">{{ imageEncoding || '未选择图片' }}</span>
        </p>
      </div>

      <!-- 第二张图片上传区域 -->
      <div class="upload-col">
        <p class="label-text">第二张比对图片</p>
        <el-upload
          class="upload-box"
          action="#"
          :auto-upload="false"
          :on-change="handleFileChange2"
          :file-list="fileList2"
          :before-remove="handleBeforeRemove"
          accept="image/jpg,image/jpeg,image/png,image/bmp"
          list-type="picture-card"
          :disabled="!image1Base64"
        >
          <i class="el-icon-plus upload-plus"></i>
        </el-upload>
        <p class="format-desc">
          需与第一张图片格式一致<br>
          格式要求: <span class="required-format">{{ imageEncoding || '请先选择第一张图片' }}</span>
        </p>
      </div>
    </div>

    <div class="action-bar">
      <el-button
        type="primary"
        @click="handleCompare"
        :disabled="!isBtnEnabled"
      >
        开始人脸比对
      </el-button>
      <span class="tip-text" v-if="!isBtnEnabled">请选择两张格式一致的图片后再比对</span>
    </div>

    <!-- 结果展示区域 -->
    <div class="result-area" v-if="compareResult">
      <h3 class="result-header">人脸比对结果</h3>
      <el-table :data="[compareResult.overview]" border style="width: 100%; margin-top: 12px;">
        <el-table-column label="比对状态" prop="status" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.status === 'success' ? 'success' : 'danger'">
              {{ scope.row.status === 'success' ? '匹配成功' : '匹配失败' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="相似度" prop="similarity" align="center"></el-table-column>
        <el-table-column label="是否同一人" prop="isSamePerson" align="center">
          <template #default="scope">
            <el-icon :class="scope.row.isSamePerson ? 'text-success' : 'text-danger'">
              <Check v-if="scope.row.isSamePerson" />
              <Close v-else />
            </el-icon>
          </template>
        </el-table-column>
        <el-table-column label="讯飞请求ID" prop="sid" align="center"></el-table-column>
        <el-table-column label="比对时间" prop="compareTime" align="center"></el-table-column>
        <el-table-column label="图片格式" prop="imageEncoding" align="center"></el-table-column>
      </el-table>

      <!-- <h3 class="result-header">讯飞原始响应 (Base64解码后)</h3> -->
      <!-- <pre class="raw-response">{{ JSON.stringify(compareResult.rawData, null, 2) }}</pre> -->
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
// 修正：正确导入 ElLoading 组件
import { ElMessage, ElMessageBox, ElTag, ElIcon, ElLoading } from 'element-plus'
import { Check, Close } from '@element-plus/icons-vue'
import faceCompareApi from '@/api/FaceCompare/faceCompare'

// 状态管理：图片文件列表、Base64、编码、结果
const fileList1 = ref([])
const fileList2 = ref([])
const image1Base64 = ref('')
const image2Base64 = ref('')
const imageEncoding = ref('')
const compareResult = ref(null)

// 计算属性：按钮是否可点击（两张图均有Base64且格式一致）
const isBtnEnabled = computed(() => {
  return !!image1Base64.value && !!image2Base64.value && !!imageEncoding.value
})

// MIME类型转讯飞支持的编码（如 image/png → png）
const getImageEncoding = (mime) => {
  const mimeMap = {
    'image/jpg': 'jpg',
    'image/jpeg': 'jpeg',
    'image/png': 'png',
    'image/bmp': 'bmp'
  }
  return mimeMap[mime] || 'jpg'
}

// 移除Base64中的空白符（与后端逻辑一致）
const removeWhitespace = (str) => str.replace(/\s+/g, '')

// 图片移除前的确认逻辑
const handleBeforeRemove = (file, fileList) => {
  return ElMessageBox.confirm(`确定移除图片【${file.name}】吗？`).then(
    () => {
      // 若移除第一张，清空第二张及编码；若移除第二张，仅清空第二张
      if (fileList === fileList1.value) {
        image1Base64.value = ''
        imageEncoding.value = ''
        fileList2.value = []
        image2Base64.value = ''
      } else {
        image2Base64.value = ''
      }
      return true
    },
    () => false
  )
}

// 第一张图片选择事件：解析Base64、编码，校验第二张格式 + 标记status为success
const handleFileChange1 = (file) => {
  // 关键：复制文件并设置status为success，使Upload组件显示预览、隐藏选择框
  const newFile = { ...file, status: 'success' }
  fileList1.value = [newFile]

  const reader = new FileReader()
  reader.readAsDataURL(file.raw)
  reader.onload = (e) => {
    const base64Arr = e.target.result.split(',')
    if (base64Arr.length < 2) {
      ElMessage.error('图片Base64格式错误')
      fileList1.value = []
      return
    }
    image1Base64.value = removeWhitespace(base64Arr[1]) // 去除空白符
    const encoding = getImageEncoding(file.raw.type)
    imageEncoding.value = encoding

    // 若已选第二张，校验格式一致性
    if (fileList2.value.length > 0) {
      const secondEncoding = getImageEncoding(fileList2.value[0].raw.type)
      if (encoding !== secondEncoding) {
        ElMessage.warning(`第一张图格式变更为【${encoding}】，第二张图【${secondEncoding}】不匹配，请重新选择`)
        fileList2.value = []
        image2Base64.value = ''
      }
    }
  }
  reader.onerror = () => {
    ElMessage.error(`图片【${file.name}】读取失败`)
    fileList1.value = []
  }
}

// 第二张图片选择事件：校验与第一张格式一致，解析Base64 + 标记status为success
const handleFileChange2 = (file) => {
  const currentEncoding = getImageEncoding(file.raw.type)
  if (currentEncoding !== imageEncoding.value) {
    ElMessage.error(`第二张图格式【${currentEncoding}】与第一张图【${imageEncoding.value}】不匹配`)
    return
  }
  // 关键：复制文件并设置status为success
  const newFile = { ...file, status: 'success' }
  fileList2.value = [newFile]

  const reader = new FileReader()
  reader.readAsDataURL(file.raw)
  reader.onload = (e) => {
    const base64Arr = e.target.result.split(',')
    if (base64Arr.length < 2) {
      ElMessage.error('图片Base64格式错误')
      fileList2.value = []
      return
    }
    image2Base64.value = removeWhitespace(base64Arr[1]) // 去除空白符
  }
  reader.onerror = () => {
    ElMessage.error(`图片【${file.name}】读取失败`)
    fileList2.value = []
  }
}

// 触发人脸比对（含加载态、结果解析）
const handleCompare = async () => {
  try {
    await ElMessageBox.confirm('确定开始人脸比对？比对过程约1-3秒，请耐心等待', '确认比对', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'info'
    })

    // 修正：使用 ElLoading.service 创建加载实例
    const loading = ElLoading.service({
      message: '比对中...',
      lock: true,
      target: '.face-compare-page'
    })

    // 调用后端接口，传递Base64和编码
    const res = await faceCompareApi.compare({
      image1: image1Base64.value,
      image2: image2Base64.value,
      imageEncoding: imageEncoding.value
    })

    // 关闭加载
    loading.close()

    if (res.code === 200) {
      const data = res.data
      // 格式化结果用于页面展示
      compareResult.value = {
        overview: {
          status: data.score >= 0.8 ? 'success' : 'fail', // 相似度≥0.8视为成功
          similarity: data.score.toFixed(4),
          isSamePerson: data.score >= 0.8,
          sid: data.sid, // 讯飞请求ID
          compareTime: new Date().toLocaleString(),
          imageEncoding: imageEncoding.value
        },
        rawData: data.rawText // 原始解析结果
      }
      ElMessage.success('比对完成')
    } else {
      ElMessage.error(res.msg || '比对失败')
    }
  } catch (error) {
    if (error.name !== 'Cancel') { // 排除用户取消操作
      ElMessage.error(error.message || '操作异常')
    }
  }
}
</script>

<style scoped>
.face-compare-page {
  padding: 24px;
  background-color: #fff;
}

.page-title {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 24px;
  color: #333;
}

.upload-row {
  display: flex;
  gap: 40px;
  margin-bottom: 24px;
}

.upload-col {
  flex: 1;
}

.label-text {
  font-size: 14px;
  color: #666;
  margin-bottom: 8px;
}

.upload-box {
  margin-bottom: 12px;
}

.upload-plus {
  font-size: 28px;
  color: #dcdcdc;
}

.format-desc {
  font-size: 12px;
  color: #999;
  line-height: 1.5;
  margin: 0;
}

.current-format,
.required-format {
  color: #409eff;
  font-weight: 500;
}

.action-bar {
  display: flex;
  align-items: center;
  margin-bottom: 24px;
}

.tip-text {
  margin-left: 16px;
  font-size: 12px;
  color: #999;
}

.result-area {
  background-color: #f9fafc;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.result-header {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 12px;
  color: #333;
}

.raw-response {
  background-color: #fff;
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  font-size: 12px;
  color: #333;
  overflow-x: auto;
  white-space: pre-wrap;
}
</style>
